#include "cc_memory.h"
#include "cc_stdlib.h"

#pragma warning(disable:4213)

void * __cdecl cc_memccpy(
	void *dest, 
	const void *src,
	int c,
	size_t count
	)
{
	/*  cc 2011-6-5 12:20:13 coding
	size_t copyCount = 0;
	int meetCharC = 0;
	char *charDest = dest;
	const char *charSrc = src;
	while(copyCount < count && *charSrc != '\0')
	{
		*charDest = *charSrc;
		++copyCount;

		if(*charSrc == c)
		{
			meetCharC = 1;
			++charDest;
			break;
		}

		++charDest;
		++charSrc;
	}

	return (meetCharC ? charDest : NULL);
	*/

	// microsoft coding version
	while(count && 
		(*(((char *)dest = (char *)dest + 1) - 1) = *(((char *)src = (char *)src + 1) - 1)) != c)
	--count;

	return (count ? dest : NULL);
}

void * __cdecl cc_memcpy(
	void *dest,
	const void *src,
	size_t cnt
	)
{
	while(cnt--)
	{
		*((char *)dest)++ = *((char *)src)++;
	}
	return (char *)dest - cnt;
}

// the declaration isn't right!
void __cdecl cc_memcpy_s(
	void *dest,
	size_t destSize,
	const void *src,
	size_t srcSize
	)
{
	while(destSize-- && srcSize--)
	{
		*((char *)dest)++ = *((char *)src)++;
	}
}

// Because memchr will confict with system library, I just can name a differant name.
// what a pity! And Shit!
void * __cdecl cc_memchr(
	const void *buf,
	int c,
	size_t cnt
	)
{
	while(cnt && *(((unsigned char *)buf = (unsigned char *)buf + 1) - 1) != c)
		--cnt;

	return (cnt ? --(char *)buf : NULL);
}

int __cdecl cc_memcmp(
	const void *buf1,
	const void *buf2,
	size_t cnt
	)
{
	while(cnt && *(char *)buf1 == *(char *)buf2)
	{
		++(char *)buf1;
		++(char *)buf2;
		--cnt;
	}

	// return (cnt ? ((*(char *)buf1 > *(char *)buf2 ? 1 : -1)) : 0);
	return (cnt ? (*(char *)buf1 - *(char *)buf2) : 0);
}

int __cdecl cc_memicmp(
	const void *buf1,
	const void *buf2,
	size_t cnt
	)
{
	const char *buf1Str = (const char *)buf1;
	const char *buf2Str = (const char *)buf2;

	while(cnt && (*buf1Str == *buf2Str || (*buf1Str - *buf2Str == 32) || (*buf1Str - *buf2Str == -32)))
	{
		++buf1Str;
		++buf2Str;
		--cnt;
	}

	return (cnt ? 
		((*buf1Str - *buf2Str == 32 || *buf1Str - *buf2Str == -32) ? 0 : (*buf1Str - *buf2Str)) : 0);
}

void * __cdecl cc_memmove(
	void *dest,
	const void *src,
	size_t cnt
	)
{
	if(dest <= src || (char *)src + cnt <= (char *)dest)
	{
		return cc_memcpy(dest, src, cnt);
	}
	else
	{
		const char *srcMaxPointer = (const char *)src + cnt - 1;
		char *destMaxPointer = (char *)dest + cnt - 1;
		while(cnt--)
		{
			*destMaxPointer-- = *srcMaxPointer--;
		}
		return dest;
	}
}

void __cdecl cc_memmove_s(
	void *dest,
	size_t destLen,
	const void *src,
	size_t srcLen
	)
{
	if(dest <= src || (char *)src + srcLen <= (char *)dest)
	{
		cc_memcpy_s(dest, destLen, src, srcLen);
	}
	else
	{
		const char *srcMaxPointer = (const char *)src + srcLen - 1;
		char *destMaxPointer = (char *)dest + srcLen - 1;
		while(srcLen--)
		{
			*destMaxPointer-- = *srcMaxPointer--;
		}
	}
}

void * __cdecl cc_memset(
	void *buf,
	int c,
	size_t cnt
	)
{
	void *ret = buf;
	while(cnt--)
	{
		*((unsigned char *)buf)++ = (unsigned char)c;
	}

	// retun (ret);  // It's strange that this works!
	return ret;
}

void cc_bzero(
	void *buf,
	size_t len
	)
{
	cc_memset(buf, 0, len);
}